/*
 * @Date         : 2022-03-03 16:10:58
 * @LastEditors  : zu1662
 * @LastEditTime : 2022-03-03 19:04:20
 * @Description  : 明亮主题和暗黑主题 Hook
 * 
 * Copyright © 2022 by zu1662, All Rights Reserved. 
 */

import { useCallback, useEffect } from "react"
import { AppTheme } from "@/types/app"
import { useStore } from "@/store"

/**
 * @description: 主题切换 Hook 封装。因为使用了 Store 内数据，使用的组件内需要进行 observer
 * @param {boolean} system 是否跟随系统主题。跟随系统后，无法手动更改主题
 * @return {*} [theme, updateTheme]
 */
const useTheme = (system?: boolean): [string, (theme?: AppTheme) => void]  => {
  const { appStore } = useStore()
  const { theme, changeTheme } = appStore

  useEffect(() => {
      // 使用系统主题时，进行判断并设置对应主题
    if(system) {
      const handleChangeTheme = (isDark: boolean) => {
        const targetTheme = isDark ? 'dark' : 'light'
        document.body.setAttribute('theme-mode', targetTheme)
        changeTheme(targetTheme)
      }
      const mql = window.matchMedia('(prefers-color-scheme: dark)')
      handleChangeTheme(mql.matches)
      // 使用事件监听，主题更改时，进行更新
      const mediaListener = (e: MediaQueryListEvent) => {
        handleChangeTheme(e.matches)
      }
      mql.addListener(mediaListener)

      return () => {
        mql.removeListener(mediaListener)
      }
    }
    return
  }, [changeTheme, system])

  // 更改主题函数
  const updateTheme = useCallback((targetTheme?: AppTheme) => {
    // 跟随系统主题，无法更改
    if(system) return
    // 没有 theme 传入，则根据目前状态进行 toggle 切换
    if(!targetTheme) {
      const isDark = document.body.getAttribute('theme-mode') === 'dark'
      targetTheme = isDark ? 'light' : 'dark'
    }
    // 设置 theme
    document.body.setAttribute('theme-mode', targetTheme)
    changeTheme(targetTheme)
  }, [changeTheme, system])

  return [theme, updateTheme]
}

export default useTheme